package com.witframework.meta;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Version;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;

import org.javalid.annotations.validation.MaxLength;
import org.javalid.annotations.validation.MinLength;

import com.witframework.WitException;
import com.witframework.core.annotations.Wit;
import com.witframework.util.BeanUtils;


public class MetaTool{
	public static MetaEntity entityMeta(Class clazz){
		MetaEntity metaEntity=new MetaEntity(clazz.getName());
		Annotation[] classAnnotations=clazz.getAnnotations();
		for(Annotation annotation:classAnnotations){
			if(annotation instanceof Wit){
				Wit witAnnotation=(Wit)annotation;
				if(witAnnotation.locked())
					throw new WitException("Can't modify the code by the tools.");
				metaEntity.setDisplayName( witAnnotation.cnname() );
				metaEntity.setDescription(witAnnotation.description());
				
			}else if(annotation instanceof Table){
				Table tableAnnotation=(Table)annotation;
				metaEntity.setTableName(tableAnnotation.name());
			}
		}
		
		List<Field> fields=BeanUtils.getFields(clazz);//BeanUtils.getAllField(clazz, BaseEntity.class);		
		for(Field field:fields){
			MetaEntityField metaEntityField=new MetaEntityField(field.getName());
			Annotation[] annotations=field.getAnnotations();
			for(Annotation annotation:annotations){
				metaEntityField.setTypeName(field.getType().getSimpleName());
				if(annotation instanceof Wit){
					Wit wit=(Wit)annotation;
					metaEntityField.setDisplayName(wit.cnname());
					metaEntityField.setDescription(wit.description());					
				}else if(annotation instanceof Id){
					metaEntityField.setIsIdentity("Y");
				}else if(annotation instanceof Column){
					Column column=(Column)annotation;
					metaEntityField.setIsUnique(column.unique()?"Y":"N");
					metaEntityField.setLength(column.length());
					metaEntityField.setIsNullable(column.nullable()?"Y":"N");
					metaEntityField.setPrecision(column.precision());
					metaEntityField.setScale(column.scale());
				}else if(annotation instanceof Temporal){
					Temporal t=(Temporal)annotation;
					if(t.value().equals(TemporalType.DATE))
						metaEntityField.setTypeName(EntityFieldType.DATE);
					if(t.value().equals(TemporalType.TIME))
						metaEntityField.setTypeName(EntityFieldType.TIME);
					if(t.value().equals(EntityFieldType.TIMESTAMP))
						metaEntityField.setTypeName(EntityFieldType.TIMESTAMP);
				}else if(annotation instanceof MaxLength){
					MaxLength a=(MaxLength)annotation;
					metaEntityField.setMaxLength(String.valueOf(a.length()));
				}else if(annotation instanceof MinLength){
					MinLength a=(MinLength)annotation;
					metaEntityField.setMinLength(String.valueOf(a.length()));
				}else if(annotation instanceof Max){
					Max a=(Max)annotation;
					metaEntityField.setMaxValue(String.valueOf(a.value()));
				}else if(annotation instanceof Min){
					Min a=(Min)annotation;
					metaEntityField.setMinValue(String.valueOf(a.value()));
				}else if(annotation instanceof NotNull){
					metaEntityField.setIsNullable("N");
				}else if(annotation instanceof Past){
					metaEntityField.setPast("Y");
				}else if(annotation instanceof Future){
					metaEntityField.setFuture("Y");
				}else if(annotation instanceof Version){
					metaEntity.setHasVersion(field.getName());					
				}
			}
			metaEntity.addField(metaEntityField);
		}
		return metaEntity;
	}
}